package jnpf.service.impl;


import jnpf.common.enums.ragFlow.RagFlowApiEnum;
import jnpf.model.knowmange.KnowMangeForm;
import jnpf.model.ragFlow.common.IdReq;
import jnpf.model.ragFlow.common.RagFlowApiResult;
import jnpf.model.ragFlow.know.CreateKnowReq;
import jnpf.model.ragFlow.know.DatasetListRequest;
import jnpf.model.ragFlow.know.DatasetResp;
import jnpf.model.ragFlow.know.ParserConfig;
import jnpf.model.ragFlow.know.api.*;
import jnpf.service.RagFlowKnowService;
import jnpf.util.RagFlowApiReqUtil;
import jnpf.util.UserProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static jnpf.util.ResultHandleUtil.txtConvertObj;


@Service
public class RagFlowKnowServiceImpl implements RagFlowKnowService {
    @Value("${ragflow.url:}")
    public String API_BASE_URL;
    @Value("${ragflow.knowApiKey}")
    public String API_KEY;
    @Autowired
    private Environment environment;
    @Autowired
    public UserProvider userProvider;


    @Override
    public RagFlowApiResult createDataset(CreateKnowReq createDataSetsReq) throws Exception {
        return txtConvertObj(RagFlowApiReqUtil.sendRequest(API_BASE_URL, API_KEY, RagFlowApiEnum.CREATE_EMPTY_DATASET, new HashMap<>(), createDataSetsReq, userProvider.get().getUserId()), DatasetResp.class);
    }

    @Override
    public RagFlowApiResult deleteDataset(IdReq createDataSetsReq) throws Exception {
        return txtConvertObj(RagFlowApiReqUtil.sendRequest(API_BASE_URL, API_KEY, RagFlowApiEnum.DELETE_DATASET, new HashMap<>(), createDataSetsReq, userProvider.get().getUserId()), DatasetResp.class);
    }

    @Override
    public RagFlowApiResult updateDataset(CreateKnowReq createDataSetsReq, String datasetId) throws Exception {
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("dataset_id", datasetId);
        return txtConvertObj(RagFlowApiReqUtil.sendRequest(API_BASE_URL, API_KEY, RagFlowApiEnum.UPDATE_DATASET_LIST, objectObjectHashMap, createDataSetsReq, userProvider.get().getUserId()), DatasetResp.class);
    }

    @Override
    public RagFlowApiResult getDatasetList(DatasetListRequest createDataSetsReq) throws Exception {
        HashMap<String, String> objectObjectHashMap = new HashMap<>();
        if (createDataSetsReq.getPage() != null) {
            objectObjectHashMap.put("page", createDataSetsReq.getPage().toString());
        }
        if (createDataSetsReq.getPageSize() != null) {
            objectObjectHashMap.put("page_size", createDataSetsReq.getPageSize().toString());
        }
        if (createDataSetsReq.getOrderby() != null) {
            objectObjectHashMap.put("orderby", createDataSetsReq.getOrderby());
        }
        if (createDataSetsReq.getDesc() != null) {
            objectObjectHashMap.put("desc", createDataSetsReq.getDesc().toString());
        }
        if (createDataSetsReq.getName() != null) {
            objectObjectHashMap.put("name", createDataSetsReq.getName());
        }
        if (createDataSetsReq.getId() != null) {
            objectObjectHashMap.put("id", createDataSetsReq.getId());
        }
        return txtConvertObj(RagFlowApiReqUtil.sendRequest(API_BASE_URL, API_KEY, RagFlowApiEnum.GET_DATASET_LIST, objectObjectHashMap, null, userProvider.get().getUserId()), List.class);
    }

    @Override
    public CreateKnowReq getCreateKnowReq( KnowMangeForm knowMangeForm) {
        CreateKnowReq createDataSetsReq = createKnowReqFromConfig(knowMangeForm);
        Object img = knowMangeForm.getImg();
        if (img!= null) {
            String avatarBase64 = getImgBase64(img);
            createDataSetsReq.setAvatar(avatarBase64);
        }
        return createDataSetsReq;
    }
    public String getImgBase64(Object img) {
        String avatarBase64 = null;
        if (img instanceof List) {
            List<?> imgList = (List<?>) img;
            if (!imgList.isEmpty() && imgList.get(0) instanceof Map) {
                Map<?, ?> imgMap = (Map<?, ?>) imgList.get(0);
                String url = (String) imgMap.get("url");
                if (url != null && !url.isEmpty()) {
                    // 构建完整URL
                    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                    HttpServletRequest request = attributes.getRequest();
                    String baseUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
                    String fullUrl = baseUrl + url;
                    // 发送HTTP请求获取图片并转换为Base64
                    try {
                        avatarBase64 = getImageAsBase64(fullUrl);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return avatarBase64;
    }

    /**
     * 从配置文件中获取默认配置并创建CreateKnowReq对象
     */
    private CreateKnowReq createKnowReqFromConfig(KnowMangeForm knowMangeForm) {
        CreateKnowReq createDataSetsReq = new CreateKnowReq();
        createDataSetsReq.setName(knowMangeForm.getName());
        createDataSetsReq.setDescription(knowMangeForm.getDes());

        // 从配置文件中获取默认值
        createDataSetsReq.setPermission(environment.getProperty("defaults.permission", "me"));
        createDataSetsReq.setEmbedding_model(environment.getProperty("defaults.embedding-model", "BAAI/bge-large-zh-v1.5@BAAI"));
        createDataSetsReq.setChunk_method(environment.getProperty("defaults.chunk-method", "naive"));
        createDataSetsReq.setPagerank(Integer.parseInt(
                environment.getProperty("defaults.pagerank", "0")));

        // 设置ParserConfig配置
        ParserConfig parserConfig = new ParserConfig();
        parserConfig.setChunk_token_num(Integer.parseInt(
                environment.getProperty("defaults.chunk-token-num", "512")));
        parserConfig.setDelimiter(environment.getProperty("defaults.delimiter", "\\n"));
        parserConfig.setHtml4excel(Boolean.parseBoolean(
                environment.getProperty("defaults.html4excel", "true")));
        parserConfig.setLayout_recognize(environment.getProperty("defaults.pdf-parser", "DeepDOC"));
        parserConfig.setAuto_keywords(Integer.parseInt(
                environment.getProperty("defaults.auto-keywords", "5")));
        parserConfig.setAuto_questions(Integer.parseInt(
                environment.getProperty("defaults.auto-questions", "2")));

        // 以下配置在application-dev.yml中存在但当前未使用
        // - defaults.use-raptor: RAPTOR算法开关
        // - defaults.extract-knowledge-graph: 知识图谱提取开关
        // - defaults.entity-normalization: 实体标准化开关
        // - defaults.community-report: 社区报告生成开关
        // - defaults.entity-types: 实体类型列表

        createDataSetsReq.setParser_config(parserConfig);
        return createDataSetsReq;
    }





    /**
     * 通过URL获取图片并转换为Base64编码
     */
    private String getImageAsBase64(String imageUrl) throws IOException {
        RestTemplate restTemplate = new RestTemplate();
        // 添加超时设置
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setConnectTimeout(5000); // 连接超时5秒
        requestFactory.setReadTimeout(5000);    // 读取超时5秒
        restTemplate.setRequestFactory(requestFactory);
        // 发送HTTP请求获取图片字节数组
        ResponseEntity<byte[]> response = restTemplate.exchange(
                imageUrl,
                HttpMethod.GET,
                null,
                byte[].class
        );
        // 转换为Base64
        // 根据图片URL判断MIME类型
        String mimeType = "image/jpeg"; // 默认JPG类型
        if (imageUrl.toLowerCase().endsWith(".png")) {
            mimeType = "image/png";
        } else if (imageUrl.toLowerCase().endsWith(".gif")) {
            mimeType = "image/gif";
        }
        return "data:" + mimeType + ";base64," + Base64.getEncoder().encodeToString(response.getBody());
    }

}
